package demo.security;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.util.matcher.RequestMatcher;

import demo.security.error.DemoAccessDeniedHandler;
import demo.security.error.DemoAuthenticationEntryPoint;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{
	
	@Autowired
//	@Qualifier("MyTokenStore")
//	@Qualifier("JwtTokenStore")
	private TokenStore tokenStore;
		
	@Override
	public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
		resources.tokenStore(this.tokenStore);
		
		resources.authenticationEntryPoint(new DemoAuthenticationEntryPoint())
				.accessDeniedHandler(new DemoAccessDeniedHandler());
	}


//	@RequestMapping(value="principal", method=RequestMethod.GET)
//    public Object getPrincipal() {
//        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        return principal;
//    }
//
//	@RequestMapping(value="roles", method=RequestMethod.GET)
//    public Object getRoles() {
//        return SecurityContextHolder.getContext().getAuthentication().getAuthorities();
//	}
	
	// @formatter:off
	@Override
	public void configure(HttpSecurity http) throws Exception {
		log.debug("***ResourceServerConfiguration:configure(HttpSecurity http): {}",http);
//		http.authorizeRequests().anyRequest().authenticated();
		
		http
			.requestMatcher(new RequestMatcher() {
				@Override
				public boolean matches(HttpServletRequest request) {
					boolean isMatched = false;
						
					String authorization = request.getHeader("Authorization");
					if(authorization != null 
							&& (authorization.startsWith(OAuth2AccessToken.BEARER_TYPE) 
									|| authorization.startsWith("Basic"))) {
						isMatched = true;
					}
					//check if access token exists
					String accessToken = request.getParameter(OAuth2AccessToken.ACCESS_TOKEN);
					if(accessToken != null) {
						isMatched = true;
					}
								
					log.debug("*****ResourceServerConfiguration RequestMatcher: isMatched:{}, authorization:{}, accessToken:{}, requestURI:{}",isMatched, authorization,accessToken, request.getRequestURI());
					
					return isMatched;
				}			
			})			
			.authorizeRequests()	
			.anyRequest().authenticated();	
		
	}
	// @formatter:on
}
